home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / widgets-mesa / src / GLwDrawingArea.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-31  |  20.3 KB  |  648 lines

  1. /* GLwDrawingArea.c -- Mesa GL Widget for X11 Toolkit Programming
  2.    Copyright (C) 1995, 1996 by
  3.      Jeroen van der Zijp <jvz@cyberia.cfdrc.com>
  4.      Thorsten Ohl <Thorsten.Ohl@Physik.TH-Darmstadt.de>
  5.  
  6.    This library is free software; you can redistribute it and/or
  7.    modify it under the terms of the GNU Library General Public
  8.    License as published by the Free Software Foundation; either
  9.    version 2 of the License, or (at your option) any later version.
  10.  
  11.    This library is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU Library General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU Library General Public
  17.    License along with this library; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.    $Id: GLwDrawingArea.c,v 1.24 1996/09/30 00:21:06 ohl Exp $
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <stdarg.h>
  26. #include <assert.h>
  27. #include <math.h>
  28. #include <float.h>
  29. #include <X11/X.h>
  30. #include <X11/Xlib.h>
  31. #include <X11/IntrinsicP.h>
  32. #include <X11/StringDefs.h>
  33. #include <X11/Shell.h>
  34. #ifdef __GLX_MOTIF
  35. #include <Xm/XmP.h>
  36. #include <Xm/PrimitiveP.h>
  37. #include <GL/GLwMDrawAP.h>
  38. #else
  39. #include <X11/CoreP.h>
  40. #include <GL/GLwDrawAP.h>
  41. #endif
  42. #include <X11/Xatom.h>
  43. #ifdef HAVE_XMU
  44. #include <X11/Xmu/StdCmap.h>  /* for XmuLookupStandardColormap */
  45. #endif
  46.  
  47. #ifdef __GLX_MOTIF
  48. #define GLwDrawingAreaWidget      GLwMDrawingAreaWidget
  49. #define GLwDrawingAreaClassRec    GLwMDrawingAreaClassRec
  50. #define GLwDrawingAreaRec         GLwMDrawingAreaRec
  51. #define glwDrawingAreaClassRec    glwMDrawingAreaClassRec
  52. #define glwDrawingAreaWidgetClass glwMDrawingAreaWidgetClass
  53. #endif
  54.  
  55. /* Actions */
  56.  
  57. static void glwInput (Widget w, XEvent * event, String * params, Cardinal * numParams);
  58.  
  59.  
  60. /* Methods */
  61.  
  62. static void ClassInitialize (void);
  63. static void Initialize (GLwDrawingAreaWidget req, GLwDrawingAreaWidget new,
  64.             ArgList args, Cardinal * num_args);
  65. static void Realize (Widget w, Mask * valueMask, XSetWindowAttributes * attributes);
  66. static void Redraw (GLwDrawingAreaWidget w, XEvent * event, Region region);
  67. static void Resize (GLwDrawingAreaWidget glw);
  68. static void Destroy (GLwDrawingAreaWidget glw);
  69.  
  70.  
  71. /* Translations */
  72.  
  73. static char defaultTranslations[] =
  74. "<KeyDown>:   glwInput() \n\
  75.    <KeyUp>:     glwInput() \n\
  76.    <BtnDown>:   glwInput() \n\
  77.    <BtnUp>:     glwInput() \n\
  78.    <BtnMotion>: glwInput() ";
  79.  
  80.  
  81. static XtActionsRec actions[] =
  82. {
  83.   {"glwInput", (XtActionProc) glwInput},    /* key or mouse input */
  84. };
  85.  
  86. static XtResource resources[] =
  87. {
  88. #undef offset
  89. #define offset(_field) XtOffset (GLwDrawingAreaWidget, glwDrawingArea._field)
  90.   {GLwNattribList, GLwCAttribList, XtRPointer, sizeof (int *),
  91.    offset (attribList), XtRImmediate, (caddr_t) NULL},
  92.   {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
  93.    offset (visualInfo), XtRImmediate, (caddr_t) NULL},
  94.   {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
  95.    offset (installColormap), XtRImmediate, (caddr_t) True},
  96.   {GLwNallocateBackground, GLwNallocateOtherColors, XtRBoolean, sizeof (Boolean),
  97.    offset (allocateBackground), XtRImmediate, (caddr_t) False},
  98.   {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
  99.    offset (allocateOtherColors), XtRImmediate, (caddr_t) False},
  100.   {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
  101.    offset (installBackground), XtRImmediate, (caddr_t) True},
  102.   {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  103.    offset (ginitCallback), XtRImmediate, (XtPointer) NULL},
  104.   {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  105.    offset (inputCallback), XtRImmediate, (XtPointer) NULL},
  106.   {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  107.    offset (resizeCallback), XtRImmediate, (XtPointer) NULL},
  108.   {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  109.    offset (exposeCallback), XtRImmediate, (XtPointer) NULL},
  110.   {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
  111.    offset (bufferSize), XtRImmediate, (caddr_t) 0},
  112.   {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
  113.    offset (level), XtRImmediate, (caddr_t) 0},
  114.   {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
  115.    offset (rgba), XtRImmediate, (caddr_t) False},
  116.   {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
  117.    offset (doublebuffer), XtRImmediate, (caddr_t) False},
  118.   {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
  119.    offset (stereo), XtRImmediate, (caddr_t) False},
  120.   {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
  121.    offset (auxBuffers), XtRImmediate, (caddr_t) 0},
  122.   {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
  123.    offset (redSize), XtRImmediate, (caddr_t) 1},
  124.   {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
  125.    offset (greenSize), XtRImmediate, (caddr_t) 1},
  126.   {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
  127.    offset (blueSize), XtRImmediate, (caddr_t) 1},
  128.   {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
  129.    offset (alphaSize), XtRImmediate, (caddr_t) 0},
  130.   {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
  131.    offset (depthSize), XtRImmediate, (caddr_t) 0},
  132.   {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
  133.    offset (stencilSize), XtRImmediate, (caddr_t) 0},
  134.   {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  135.    offset (accumRedSize), XtRImmediate, (caddr_t) 0},
  136.   {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  137.    offset (accumGreenSize), XtRImmediate, (caddr_t) 0},
  138.   {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  139.    offset (accumBlueSize), XtRImmediate, (caddr_t) 0},
  140.   {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
  141.    offset (accumAlphaSize), XtRImmediate, (caddr_t) 0},
  142. #ifdef __GLX_MOTIF
  143.   {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
  144.    XtOffset (GLwDrawingAreaWidget, primitive.traversal_on),
  145.    XmRImmediate, (XtPointer) FALSE},
  146.   {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
  147.    XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
  148.    XmRImmediate, (XtPointer) FALSE},
  149.   {XmNhighlightThickness, XmCHighlightThickness,
  150.    XmRHorizontalDimension, sizeof (Dimension),
  151.    XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
  152.    XmRImmediate, (XtPointer) 0},
  153. #endif
  154.   {GLwNdebug, GLwCDebug, XtRBoolean, sizeof (Boolean),
  155.    offset (debug), XtRImmediate, (caddr_t) False},
  156. #undef offset
  157. };
  158.  
  159.  
  160. GLwDrawingAreaClassRec glwDrawingAreaClassRec =
  161. {
  162.   {                /* Core fields */
  163. #ifdef __GLX_MOTIF
  164.     /* superclass               */ (WidgetClass) & xmPrimitiveClassRec,
  165.     /* class_name               */ "GLwMDrawingArea",
  166. #else
  167.     /* superclass               */ (WidgetClass) & coreClassRec,
  168.     /* class_name               */ "GLwDrawingArea",
  169. #endif
  170.     /* widget_size              */ sizeof (GLwDrawingAreaRec),
  171.     /* class_initialize         */ ClassInitialize,
  172.     /* class_part_initialize    */ NULL,
  173.     /* class_inited             */ FALSE,
  174.     /* initialize               */ (XtInitProc) Initialize,
  175.     /* initialize_hook          */ NULL,
  176.     /* realize                  */ Realize,
  177.     /* actions                  */ actions,
  178.     /* num_actions              */ XtNumber (actions),
  179.     /* resources                */ resources,
  180.     /* num_resources            */ XtNumber (resources),
  181.     /* xrm_class                */ NULLQUARK,
  182.     /* compress_motion          */ TRUE,
  183.     /* compress_exposure        */ TRUE,
  184.     /* compress_enterleave      */ TRUE,
  185.     /* visible_interest         */ TRUE,
  186.     /* destroy                  */ (XtWidgetProc) Destroy,
  187.     /* resize                   */ (XtWidgetProc) Resize,
  188.     /* expose                   */ (XtExposeProc) Redraw,
  189.     /* set_values               */ NULL,
  190.     /* set_values_hook          */ NULL,
  191.     /* set_values_almost        */ XtInheritSetValuesAlmost,
  192.     /* get_values_hook          */ NULL,
  193.     /* accept_focus             */ NULL,
  194.     /* version                  */ XtVersion,
  195.     /* callback_private         */ NULL,
  196.     /* tm_table                 */ defaultTranslations,
  197.     /* query_geometry           */ XtInheritQueryGeometry,
  198.     /* display_accelerator      */ XtInheritDisplayAccelerator,
  199.     /* extension                */ NULL
  200.   },
  201. #ifdef __GLX_MOTIF
  202.   {                /* XmPrimitive fields */
  203.     /* border_highlight         */ (XtWidgetProc) _XtInherit,
  204.     /* border_unhighlight       */ (XtWidgetProc) _XtInherit,
  205.     /* translations             */ XtInheritTranslations,
  206.     /* arm_and_activate         */ NULL,
  207.     /* get_resources            */ NULL,
  208.     /* num get_resources        */ 0,
  209.     /* extension                */ NULL,
  210.   }
  211. #endif /* __GLX_MOTIF */
  212. };
  213.  
  214. WidgetClass glwDrawingAreaWidgetClass = (WidgetClass) & glwDrawingAreaClassRec;
  215.  
  216.  
  217. static void
  218. error (Widget w, char *string)
  219. {
  220.   char buf[256];
  221.   sprintf (buf, "%s: %s: %s\n",
  222.        XtClass(w)->core_class.class_name, w->core.name, string);
  223.   XtAppError (XtWidgetToApplicationContext (w), buf);
  224. }
  225.  
  226. static void
  227. warning (Widget w, char *string)
  228. {
  229.   char buf[256];
  230.   sprintf (buf, "%s: %s: %s\n",
  231.        XtClass(w)->core_class.class_name, w->core.name, string);
  232.   XtAppWarning (XtWidgetToApplicationContext (w), buf);
  233. }
  234.  
  235. static Widget
  236. toplevel_widget (Widget w)
  237. {
  238.   Widget p;
  239.   for (p = XtParent (w); !XtIsShell (p); p = XtParent (p))
  240.     if (p == NULL)
  241.       {
  242.     p = w;
  243.     error (w, "can't find shell widget");
  244.       }
  245.   return p;
  246. }
  247.  
  248. /* Create attribute list for passing to glxChooseVisual()
  249.    from the ressources.  */
  250.  
  251. #define ATTRIBLIST_SIZE 30
  252. static void
  253. generate_attrib_list (GLwDrawingAreaPart *p)
  254. {
  255.   int i = 0;
  256.   p->attribList = (int *) XtCalloc (ATTRIBLIST_SIZE, sizeof (int));
  257.   p->attribList_allocated = True;
  258.  
  259.   p->attribList[i++] = GLX_BUFFER_SIZE;
  260.   p->attribList[i++] = p->bufferSize;
  261.   p->attribList[i++] = GLX_LEVEL;
  262.   p->attribList[i++] = p->level;
  263.   if (p->rgba)
  264.     p->attribList[i++] = GLX_RGBA;
  265.   if (p->doublebuffer)
  266.     p->attribList[i++] = GLX_DOUBLEBUFFER;
  267.   if (p->stereo)
  268.     p->attribList[i++] = GLX_STEREO;
  269.   p->attribList[i++] = GLX_AUX_BUFFERS;
  270.   p->attribList[i++] = p->auxBuffers;
  271.   p->attribList[i++] = GLX_RED_SIZE;
  272.   p->attribList[i++] = p->redSize;
  273.   p->attribList[i++] = GLX_GREEN_SIZE;
  274.   p->attribList[i++] = p->greenSize;
  275.   p->attribList[i++] = GLX_BLUE_SIZE;
  276.   p->attribList[i++] = p->blueSize;
  277.   p->attribList[i++] = GLX_ALPHA_SIZE;
  278.   p->attribList[i++] = p->alphaSize;
  279.   p->attribList[i++] = GLX_DEPTH_SIZE;
  280.   p->attribList[i++] = p->depthSize;
  281.   p->attribList[i++] = GLX_STENCIL_SIZE;
  282.   p->attribList[i++] = p->stencilSize;
  283.   p->attribList[i++] = GLX_ACCUM_RED_SIZE;
  284.   p->attribList[i++] = p->accumRedSize;
  285.   p->attribList[i++] = GLX_ACCUM_GREEN_SIZE;
  286.   p->attribList[i++] = p->accumGreenSize;
  287.   p->attribList[i++] = GLX_ACCUM_BLUE_SIZE;
  288.   p->attribList[i++] = p->accumBlueSize;
  289.   p->attribList[i++] = GLX_ACCUM_ALPHA_SIZE;
  290.   p->attribList[i++] = p->accumAlphaSize;
  291.   p->attribList[i++] = None;
  292. }
  293.  
  294. #ifdef XmuLookupStandardColormap_OK
  295. static Colormap
  296. get_standard_rgb_map (Widget w, XVisualInfo *vi)
  297. {
  298.   Colormap cmap = None;
  299.  
  300. #ifdef HAVE_XMU
  301.   Display *dpy = XtDisplay (w);
  302.   int scr = XScreenNumberOfScreen (XtScreen (w));
  303.   
  304.   if (XmuLookupStandardColormap (dpy, vi->screen, vi->visualid, vi->depth,
  305.                  XA_RGB_DEFAULT_MAP, False, True))
  306.     {
  307.       XStandardColormap *std_cmaps;
  308.       int i, num_cmaps;
  309.       if (XGetRGBColormaps (dpy, RootWindow (dpy, scr),
  310.                 &std_cmaps, &num_cmaps, XA_RGB_DEFAULT_MAP))
  311.     {
  312.       for (i = 0; i < num_cmaps; i++)
  313.         if (std_cmaps[i].visualid == vi->visualid)
  314.           {
  315.         cmap = std_cmaps[i].colormap;
  316.         break;
  317.           }
  318.       XFree (std_cmaps);
  319.     }
  320.     }
  321. #endif /* HAVE_XMU */
  322.  
  323.   return cmap;
  324. }
  325. #endif /* XmuLookupStandardColormap_OK */
  326.  
  327. #define glw_cmaps glwDrawingAreaClassRec.glwDrawingArea_class.colormaps
  328.  
  329. static Colormap
  330. lookup_colormap (Widget w, XVisualInfo *vi, int alloc)
  331. {
  332.   Display *dpy;
  333.   int scr;
  334.   Colormap cmap;
  335.   int i;
  336.  
  337.   LOG (w);
  338.  
  339.   dpy = XtDisplay (w);
  340.   scr = XScreenNumberOfScreen (XtScreen (w));
  341.   cmap = None;
  342.  
  343. #ifdef DEBUG
  344.   if (GLwDebug(w))
  345.     fprintf (stderr,
  346.          "looking up colormap for visual id #%ld on display #%p ... ",
  347.          vi->visualid, dpy);
  348. #endif
  349.  
  350.   assert (glw_cmaps.entries);
  351.   
  352.   for (i = 0; i < glw_cmaps.next_entry; i++)
  353.     if ((glw_cmaps.entries[i].dpy == dpy)
  354.     && (glw_cmaps.entries[i].vid == vi->visualid))
  355.       {
  356. #ifdef DEBUG
  357.     if (GLwDebug(w))
  358.       fprintf (stderr, "found #%ld\n", glw_cmaps.entries[i].cmap);
  359. #endif
  360.     return glw_cmaps.entries[i].cmap;
  361.       }
  362.  
  363. #ifdef XmuLookupStandardColormap_OK
  364.   /* Commented out as of version 1.2.8 since Sun-SGI display causes a
  365.      weird problem.  Probably a bug in Sun's XmuLookupStandardColormap().  */
  366.  
  367.   if ((vi->class == TrueColor)
  368.       || (vi->class == DirectColor))
  369.     cmap = get_standard_rgb_map (w, vi);
  370.  
  371.   /* I had put this code (which is inspired by glut) in for a reason because
  372.      I had experienced problems with 8 bit TrueColor visuals.  Now I can't
  373.      reproduce these problem anymore.  I'll leave it in as inactive code, in
  374.      case somebody can reproduce the old problems.  */
  375. #endif
  376.  
  377.   /* Code to look for HP Color Recovery Atom and colormap contributed by
  378.      Jean-Luc Daems (jld@star.be) on Feb 23, 1996.   */
  379.   if (cmap == None) {
  380.      Atom hp_cr_maps = XInternAtom(dpy,"_HP_RGB_SMOOTH_MAP_LIST",True) ;
  381.      if (hp_cr_maps) {
  382.         XStandardColormap* colmaps = 0;
  383.         int nrColmaps = 0;
  384.         int i;
  385.         XGetRGBColormaps( dpy, RootWindow(dpy, scr),
  386.                           &colmaps, &nrColmaps, hp_cr_maps );
  387.         for (i=0; i<nrColmaps; i++) {
  388.            if (colmaps[i].visualid == vi->visual->visualid) {
  389.               cmap = colmaps[i].colormap;
  390.               break;
  391.            }
  392.         }
  393.      }
  394.   }
  395.   if (cmap == None)
  396.     cmap = XCreateColormap (dpy, RootWindow (dpy, scr), vi->visual, AllocNone);
  397.  
  398.   if (!cmap)
  399.       error (w, "can't get a colormap");
  400.  
  401.   if (glw_cmaps.next_entry >= glw_cmaps.allocated_entries)
  402.     {
  403.       glw_cmaps.allocated_entries += 10;
  404.       glw_cmaps.entries = (struct cmap_cache_entry *)
  405.     XtRealloc ((char *) glw_cmaps.entries,
  406.            glw_cmaps.allocated_entries
  407.            * sizeof (struct cmap_cache_entry));
  408.     }
  409.   
  410.   i = glw_cmaps.next_entry++;
  411.   glw_cmaps.entries[i].dpy = dpy;
  412.   glw_cmaps.entries[i].vid = vi->visualid;
  413.   glw_cmaps.entries[i].cmap = cmap;
  414.  
  415. #ifdef DEBUG
  416.   if (GLwDebug(w))
  417.     fprintf (stderr, "allocated new #%ld\n", cmap);
  418. #endif
  419.   return cmap;
  420. }
  421.  
  422. /* Inform the window manager that the widget W's window needs a
  423.    special colormap by setting the WM_COLORMAP_WINDOWS property
  424.    on the top level shell.
  425.  
  426.    FIXME: we should use XGetWMColormapWindows () to check for
  427.           other windows and add our window to this list instead
  428.       of overwriting. */
  429.  
  430. static void
  431. post_colormap (Widget w)
  432. {
  433.   Widget top = toplevel_widget (w);
  434.   Window wlist[2];
  435.   wlist[0] = XtWindow(w);
  436.   wlist[1] = XtWindow(top);
  437.   if (!XSetWMColormapWindows (XtDisplay(top), XtWindow(top), wlist, 2))
  438.     warning (w, "can't post colormap");
  439. }
  440.  
  441.  
  442.  
  443. /* Widget methods.  */
  444.  
  445. /* Initialize this widget class.  Currently we just allocate the first
  446.    chunk of memory for the colormap cache.  */
  447.  
  448. static void
  449. ClassInitialize (void)
  450. {
  451.   /* two's a crowd ...  (for most applications)  */
  452.   glw_cmaps.allocated_entries = 2;
  453.   glw_cmaps.next_entry = 0;
  454.   glw_cmaps.entries = (struct cmap_cache_entry *)
  455.     XtMalloc (glw_cmaps.allocated_entries * sizeof (struct cmap_cache_entry));
  456. }
  457.  
  458. /* Initialize a widget instance.
  459.    Here's where we do the colormap dance. */
  460.  
  461. static void 
  462. Initialize (GLwDrawingAreaWidget req,
  463.         GLwDrawingAreaWidget new,
  464.         ArgList args, Cardinal *num_args)
  465. {
  466.   Display *dpy;
  467.   int scr;
  468.   XVisualInfo *vi;
  469.  
  470.   LOG (new);
  471.   
  472.   dpy = XtDisplay (new);
  473.   scr = XScreenNumberOfScreen (XtScreen (new));
  474.  
  475.   if (req->core.width == 0)
  476.     new->core.width = 100;
  477.   if (req->core.height == 0)
  478.     new->core.width = 100;
  479.  
  480.   new->glwDrawingArea.attribList_allocated = False;
  481.   new->glwDrawingArea.visualInfo_allocated = False;
  482.  
  483.   vi = new->glwDrawingArea.visualInfo;
  484.  
  485.   /* If there's no visual in the resources, we have to select our own,
  486.      based on the attribute list or the other resources.  */
  487.  
  488.   if (vi == NULL)
  489.     {
  490.       /* If the list of attribues is not defined in the resources, we
  491.      have to build one from the other resources.  */
  492.       if (new->glwDrawingArea.attribList == NULL)
  493.     generate_attrib_list (&new->glwDrawingArea);
  494.  
  495.       /* Select the visual and remember it.  */
  496.       vi = glXChooseVisual (dpy, scr, new->glwDrawingArea.attribList);
  497.       if (!vi)
  498.     error ((Widget) new, "can't get a visual");
  499.       new->glwDrawingArea.visualInfo = vi;
  500.       new->glwDrawingArea.visualInfo_allocated = True;
  501.     }
  502.  
  503.   new->core.depth = vi->depth;
  504.  
  505.   /* If we're rendering in the default visual in color-index mode,
  506.      we continue to use the default map.  This is the most economical
  507.      approach.  In RGBA mode we try to use a standard RGB map for
  508.      TrueColor and DirectColor visuals.  If this is not available
  509.      and for all other visuals, we allocate a fresh colormap. */
  510.  
  511.   if (!new->glwDrawingArea.rgba
  512.       && (vi->visualid == XVisualIDFromVisual (DefaultVisual (dpy, scr))))
  513.     new->core.colormap = DefaultColormap (dpy, scr);
  514.   else
  515.     new->core.colormap = lookup_colormap ((Widget) new, vi, AllocNone);
  516. }
  517.  
  518. /* Realize a widget.
  519.    That's trivial, we just create the window with the appropriate
  520.    visual and call the callback functions.  */
  521.  
  522. static void 
  523. Realize (Widget w, Mask *mask, XSetWindowAttributes *attr)
  524. {
  525.   GLwDrawingAreaWidget glw;
  526.   Display *dpy;
  527.   int scr;
  528.   GLwDrawingAreaCallbackStruct cb;
  529.  
  530.   LOG (w);
  531.  
  532.   glw = (GLwDrawingAreaWidget) w;
  533.   dpy = XtDisplay (w);
  534.   scr = XScreenNumberOfScreen (XtScreen (w));
  535.  
  536.   /* Create the window.  */
  537.  
  538.   attr->colormap = w->core.colormap;
  539.   attr->event_mask
  540.     = KeyPressMask
  541.     | KeyReleaseMask
  542.     | ButtonPressMask
  543.     | ButtonReleaseMask
  544.     | EnterWindowMask
  545.     | LeaveWindowMask
  546.     | PointerMotionMask
  547.     | ButtonMotionMask
  548.     | ExposureMask
  549.     | StructureNotifyMask;
  550.   attr->border_pixel = BlackPixel (dpy, scr);
  551.   attr->background_pixel = BlackPixel (dpy, scr);
  552.   attr->backing_store = NotUseful;
  553.   *mask = CWColormap
  554.         | CWEventMask
  555.     | CWBorderPixel
  556.     | CWBackPixel
  557.     | CWBackingStore;
  558.   XtCreateWindow (w, (unsigned int) InputOutput,
  559.           glw->glwDrawingArea.visualInfo->visual,
  560.           *mask, attr);
  561.  
  562.   /* Install the colormap if requested.  */
  563.   if (glw->glwDrawingArea.installColormap)
  564.     post_colormap (w);
  565.  
  566.   /* Invoke callback to initialize.  */
  567.   cb.reason = GLwCR_GINIT;
  568.   cb.event = NULL;
  569.   cb.width = glw->core.width;
  570.   cb.height = glw->core.height;
  571.   XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.ginitCallback, &cb);
  572. }
  573.  
  574. /* Invoke expose callbacks to redraw screen */
  575.  
  576. static void 
  577. Redraw (GLwDrawingAreaWidget w, XEvent * event, Region region)
  578. {
  579.   GLwDrawingAreaCallbackStruct cb;
  580.   LOG (w);
  581.   /* Ignore while not yet realized.  */
  582.   if (!XtIsRealized ((Widget) w))
  583.     return;
  584.   cb.reason = GLwCR_EXPOSE;
  585.   cb.event = event;
  586.   cb.width = w->core.width;
  587.   cb.height = w->core.height;
  588.   XtCallCallbackList ((Widget) w, w->glwDrawingArea.exposeCallback, &cb);
  589. }
  590.  
  591. /* Invoke resize callbacks */
  592.  
  593. static void 
  594. Resize (GLwDrawingAreaWidget glw)
  595. {
  596.   GLwDrawingAreaCallbackStruct cb;
  597.   LOG (glw);
  598.   /* Ignore while not yet realized.  */
  599.   if (!XtIsRealized ((Widget) glw))
  600.     return;
  601.   cb.reason = GLwCR_RESIZE;
  602.   cb.event = NULL;
  603.   cb.width = glw->core.width;
  604.   cb.height = glw->core.height;
  605.   XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.resizeCallback, &cb);
  606. }
  607.  
  608. /* Window destroy handling.
  609.  
  610.    FIXME: shouldn't we remove the WM_COLORMAP_WINDOWS property
  611.           from the toplevel shell?  */
  612.  
  613. static void 
  614. Destroy (GLwDrawingAreaWidget glw)
  615. {
  616.   LOG (glw);
  617.   XtRemoveAllCallbacks ((Widget) glw, GLwNinputCallback);
  618.   XtRemoveAllCallbacks ((Widget) glw, GLwNresizeCallback);
  619.   XtRemoveAllCallbacks ((Widget) glw, GLwNexposeCallback);
  620.   if (glw->glwDrawingArea.attribList_allocated)
  621.     {
  622.       XtFree ((char *)glw->glwDrawingArea.attribList);
  623.       glw->glwDrawingArea.attribList_allocated = False;
  624.     }
  625.   if (glw->glwDrawingArea.visualInfo_allocated)
  626.     {
  627.       XtFree ((char *)glw->glwDrawingArea.visualInfo);
  628.       glw->glwDrawingArea.visualInfo_allocated = False;
  629.     }
  630. }
  631.  
  632. /* Action routine for keyboard and mouse events */
  633.  
  634. static void 
  635. glwInput (Widget w, XEvent * event, String * params, Cardinal * numParams)
  636. {
  637.   GLwDrawingAreaCallbackStruct cb;
  638.   GLwDrawingAreaWidget glw = (GLwDrawingAreaWidget) w;
  639.   LOG (w);
  640.   cb.reason = GLwCR_INPUT;
  641.   cb.event = event;
  642.   cb.width = glw->core.width;
  643.   cb.height = glw->core.height;
  644.   XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.inputCallback, &cb);
  645. }
  646.  
  647. /* The End.  */
  648.